<?php

namespace app\common\model\merchant;

use app\common\loader\ModelMerchant;
use app\common\model\BaseModel;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\Exception;

/**
 * 商户登录信息
 * Class Merchant
 * @package app\common\model\merchant
 */
class MerchantModel extends BaseModel
{
    //
    protected $name = 'merchant';
    //
    public string $fieldId = 'id';
    // 商户编号
    public string $fieldMerId = 'mer_id';
    // 登录用户名
    public string $fieldUsername = 'username';
    // 密码
    public string $fieldPasswd = 'passwd';
    // 手机号码
    public string $fieldMobile = 'mobile';
    // 微信openid
    public string $fieldOpenId = 'open_id';
    // 微信union_id
    public string $fieldUnionId = 'union_id';
    // 商户管理员 0 普通用户, 1 管理员
    public string $fieldIsManager = 'is_manager';
    // 关联角色
    public string $fieldRoleId = 'role_id';
    // 所在部门
    public string $fieldDeptId = 'dept_id';
    // 最后登录时间
    public string $fieldLastLoginTime = 'last_login_time';
    // 最后登录IP
    public string $fieldLastLoginIp = 'last_login_ip';
    // 登录次数
    public string $fieldLoginNum = 'login_num';
    // 状态: 1正常,0禁用
    public string $fieldStatus = 'status';
    // 操作人
    public string $fieldOpUser = 'op_user';
    // 创建时间
    public string $fieldCreateAt = 'create_at';
    // 更新时间
    public string $fieldUpdateAt = 'update_at';
    // 设置字段信息
    protected $schema = [
        'id' => 'int',        //
        'mer_id' => 'string',        // 商户编号
        'username' => 'string',        // 登录用户名
        'passwd' => 'string',        // 密码
        'mobile' => 'string',        // 手机号码
        'open_id' => 'string',        // 微信openid
        'union_id' => 'string',        // 微信union_id
        'is_manager' => 'int',        // 商户管理员 0 普通用户, 1 管理员
        'role_id' => 'int',        // 关联角色
        'dept_id' => 'int',        // 所在部门
        'last_login_time' => 'datetime',        // 最后登录时间
        'last_login_ip' => 'string',        // 最后登录IP
        'login_num' => 'int',        // 登录次数
        'status' => 'int',        // 状态: 1正常,0禁用
        'op_user' => 'int',        // 操作人
        'create_at' => 'datetime',        // 创建时间
        'update_at' => 'datetime',        // 更新时间
    ];

    protected $merchatInfo = null;

    /**
     * 创建商户
     * @param array $param
     * @param int $op_user
     * @return array
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @example {title:'xx','mobile'=>'12000xxx','contact'=>'','address'=>'xxx','passwd'=>''}
     */
    public function create(array $param, int $op_user): array
    {
        // 1. 获取商品ID
        // 2. 创建默认部门
        // 3. 创建默认角色
        // 4. 创建登录信息表
        // 5. 创建基本信息
        // 6. 创建商户库存表
        $prefix = '1';
        if (app()->isDebug()) {
            $prefix = 'mer';
        }
        $mer_id = $this->getNewCode($this->name, 'mer_id', $prefix, 5);
        $param['mobile'] = trim($param['mobile']);
        $param['op_user'] = $op_user;
        $param['create_at'] = date('Y-m-d H:i:s');


        $result = [];
        try {
            $this->startTrans();
            // 创建部门
            $param['dept_id'] = ModelMerchant::MerchantDepartment()->createDefaultDept($param, $mer_id);
            // 创建角色
            $param['role_id'] = ModelMerchant::MerchantRoles()->createDefaultRole($param, $mer_id);
            // 创建登录
            $this->createDefaultLogin($param, $mer_id);

            $this->commit();
            $result = [
                'mer_id' => $mer_id,
            ];
        } catch (Exception $e) {
            $this->rollback();
        }
        return $result;
    }

    /**
     * 创建登录信息
     * @param array $param 创建参数
     * @param string $merId 商户ID
     * @return int|string
     */
    protected function createDefaultLogin(array $param, string $merId)
    {
        // 登录信息
        $loginData = [
            'mer_id' => $merId,
            'username' => $param['contact'] . $param['mobile'],
            'passwd' => md5(md5($param['passwd'])),
            'mobile' => $param['mobile'],
            'op_user' => $param['op_user'],
            'create_at' => $param['create_at'],
            'dept_id' => $param['dept_id'],
            'role_id' => $param['role_id'],
            'is_manager' => 1,
        ];
        $id = $this->db()->insertGetId($loginData);

        $end_time = $param['end_time'] ?? Dt()->Add(1, 'y')->format(2);
        // 创建其他信息
        $baseData = [
            'mer_id' => $merId,
            'title' => $param['title'],
            'company_name' => $param['title'],
            'address' => $param['address'],
            'contact' => $param['contact'],
            'update_at' => $param['create_at'],
            'mobile' => $param['mobile'],
            'assoc_manager_id' => $id,
            'entry' => md5_16($merId),
            'begin_time' => date('Y-m-d'),
            'end_time' => $end_time,
            'max_red_packet' => MAX_RED_PACKET,
            'distance' => 200,
            'restrict_location' => 1,
        ];
        $this->removeOption()->db('merchant_info')->insert($baseData);

        // 创建默认库存信息
        $stockData = [
            'mer_id' => $merId,
            'balance' => 0,        // 余额
            'virtual_num' => $param['virtual_num'] ?? 0,        // 虚码数量
            'real_num' => 0,        // 实码数量
            'update_at' => $param['create_at'],        // 更新时间
        ];
        $this->removeOption()->db('merchant_stock')->insert($stockData);
        return $id;
    }

    /**
     *  检测登录的信息是否正确, 正确返回用户信息,失败返回空,错误信息放到msg中,
     * @param array $logininfo 要检测的登录信息
     * @param string $msg 接收返回的内容
     * @return array 返回的用户信息
     * @throws \think\Exception
     */
    public function validUserInfo(array $logininfo, &$msg): array
    {
        if (empty($logininfo["id"])) {
            $msg = '用户ID不能为空';
            return [];
        }
        $adminInfo = $this->where("id", $logininfo['id'])->where("status", 1)
            ->cache(true, MINUTES_SECOND)
            ->field("id,mer_id,username,passwd,role_id,dept_id,is_manager")
            ->find();
        if (empty($adminInfo)) {
            $msg = '用户不存在或已被禁用';
            return [];
        }

        if ($logininfo["password"] !== $adminInfo["passwd"]) {
            $msg = '密码错误,请重新登录。。';
            return [];
        }
        $msg = "";
        return $adminInfo;
    }

    /**
     * 获取商户管理员的用户编号
     * @param string $mer_id
     * @return int
     */
    public function getMangerID(string $mer_id): int
    {
        return $this->removeOption()->db('merchant_info')->where('mer_id', $mer_id)
            ->value('assoc_manager_id', 0);
    }

    /**
     * 重置商店管理员密码
     * @param int $id 用户编号
     * @param string $passwd 密码
     * @param int $opUser 操作人
     * @return mixed
     * @throws \think\db\exception\DbException
     */
    public function resetPasswd(int $id, string $passwd, int $opUser)
    {
        $data = [
            'passwd' => password($passwd)
        ];
        return $this->db()->where('id', $id)->update($data);
    }

    /**
     * 编辑商户登录状态
     * @param int $id
     * @param int $status
     * @param int $opUser
     * @return mixed
     * @throws \think\db\exception\DbException
     */
    public function editStatus(int $id, int $status, int $opUser)
    {
        return $this->db()->where('id', $id)->update(['status' => $status]);
    }

    /**
     * 编辑商户的状态
     * @param string $mer_id 商户编号
     * @param int $mangerId 管理员ID
     * @param int $status 状态  0:禁用  >0 正常
     * @param int $opUser
     * @return mixed
     * @throws Exception
     * @throws \think\db\exception\DbException
     */
    public function editMerchantStatus(string $mer_id, int $mangerId, int $status, int $opUser)
    {
        try {
            $this->startTrans();
            $this->db()->where('id', $mangerId)->update(['status' => $status]);
            $result = $this->removeOption()->db('merchant_info')->where('mer_id', $mer_id)->update(['status' => $status]);
            $this->commit();
            return $result;
        } catch (Exception $e) {
            $this->rollback();
            throw $e;
        }
    }


    /**
     * 检查手机号或用户名是否存在
     * @param string $mer_id
     * @param string $mobile
     * @param string $username
     * @return int|mixed|string|null
     */
    public function checkMobile(string $mer_id, string $mobile, string $username)
    {
        if (empty($mer_id) || empty($mobile)) {
            return 0;
        }

        return $this->db()->where('mer_id', $mer_id)
            ->whereRaw('mobile=:mobile or username=:username', ['mobile' => $mobile, 'username' => $username])
            ->value('id');
    }

    /**
     * 检查商户是否存在
     * @param $where
     * @return bool
     * @throws Exception
     */
    public function checkUser($where)
    {
        $data = $this->where($where)->value([], 'id');
        if (empty($data)) {
            throw  new Exception('用户不存在', API_ERROR);
        }
        return true;
    }

    /**
     * 商户list
     * @param array $where
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws Exception
     * @throws ModelNotFoundException
     */
    public function MerchantList($where= []): array
    {
        return $this->db()
            ->where($where ?? [])
            ->field('mer_id,(case when status=1 then status else 2 end) as status,op_user')
            ->select();
    }

}
